<html>
    <head>
        <title>计时系统</title>
    </head>
    <body>
        <script>
            // 计时  Timing

                /*
                        使用时间和时区总是很棘手，尤其是如果你需要构建一个由不同时区中的用户使用的全局系统。

                        ABP提供了一个基本的基础设施，使其变得简单并尽可能自动处理。本文档涵盖了与时区相关的ABP服务和系统。

                        (如果你正在创建一个在单个时区区域运行的本地应用程序，你可能不需要所有这些系统。。但即使在这种情况下，也建议使用本文档中介绍的IClock服务。)
                */

                /*
                    一、 IClock 服务

                                DateTime.Now返回一个DateTime对象，其中包含服务器的本地日期和时间。

                                DateTime对象不存储时区信息。

                                因此，你无法知道存储在该对象中的绝对日期和时间。你只能做出假设，例如假设它是在UTC+05时区创建的。
                                
                                当你将此值保存到数据库并稍后读取它或将其发送到不同时区的客户端时，事情会变得特别复杂。

                                这个问题的一种解决方案是始终使用DateTime.UtcNow，并假设所有DateTime对象为UTC时间。这样，你可以在需要时将其转换为目标客户端的时区。


                                ★、UTC 与本地时间的区别：

                                        维度                UTC(协调世界时间)                              本地时间

                                        定义         全球同一时间标准，基于原子钟和地球自转              特定地理读取的时间(如 "北京时间： UTC+8 ")

                                        时区依赖       不依赖于地理位置，全球统一                        依赖于地理位置


                                IClock在获取当前时间时提供抽象，因此你可以在应用程序的单点控制日期时间的类型（UTC或本地）。

                                        eg: 获取当前时间：

                                                using Volo.Abp.DependencyInjection;
                                                using Volo.Abp.Timing;

                                                namespace AbpDemo
                                                {
                                                    public class MyService : ITransientDependency
                                                    {
                                                        private readonly IClock _clock;

                                                        public MyService(IClock clock)
                                                        {
                                                            _clock = clock;
                                                        }

                                                        public void Foo()
                                                        {
                                                            // 获取当前时间
                                                            var now = _clock.Now;
                                                        }
                                                    }
                                                }


                                        当你需要获取当前时间时注入IClock服务。
                                        常见的基类（如Application ationService）已经注入它并将其作为基属性提供-因此，你可以直接将其用作Clock。

                                        使用Now属性获取当前时间。

                                        （大多数时候，IClock是你需要在应用程序中了解和使用的唯一服务。）
                */

                /*
                     二、时钟选项类   AbpClockOptions

                            AbpClockOptions是用于设置时钟类型的选项类。

                            eg: 使用UTC时钟

                                    Configure<AbpClockOptions>(options =>
                                    {
                                        options.Kind = DateTimeKind.Utc;
                                    });

                            将此写入模块的ConfigureServices方法中。

                            默认的Kind是Unspecified，这有效地禁用了时钟功能。如果你想获得时钟系统的好处，请将其设为Utc或Local。


                */

                /*
                     三、DataTime  规范化


                        1、IColock.Normalize()

                                IClock的另一个重要功能是规范化DateTime对象。

                                eg：  

                                        DateTime dateTime = ...; // 从某处获取时间
                                        var normalizedDateTime = Clock.Normalize(dateTime)  // 规范化时间

                                Normalize方法的工作原理如下：

                                    如果当前时钟是UTC并且给定的DateTime是本地的，则将给定的DateTime转换为UTC（通过使用DateTime.ToUniversalTime()方法）。

                                    如果当前时钟是本地的并且给定的DateTime是UTC，则将给定的DateTime转换为本地的（通过使用DateTime.ToLocalTime()方法）。

                                    如果给定DateTime的Kind是Unspecified，则将给定DateTime的Kind（使用DateTime.SpecifyKind(...)方法）设置为当前时钟的Kind。
                            

                                Normalize方法由ABP 使用，当它得到一个不是有 IClock.Now 创建的DataTime 并且可能与单管始终类型不兼容时。

                                        eg：
                                            DateTime类型绑定在ASP.NETCore MVC模型绑定中。

                                            通过Entity Framework Core将数据保存到数据库并从数据库中读取数据。

                                            在JSON反序列化上使用DateTime对象。

                        2、[DisableDateTimeNormalization] 特性 (禁用规范化时间)

                                    DisableDateTimeNormalization 特性可用于禁用所需类或属性的规范化操作
                                
                */

                /*
                    四、IClock的其他属性

                                除了Now，  IClock服务还具有以下属性：
                                        
                                Kind：返回当前使用的时钟类型的DateTimeKind（DateTimeKind.Utc、DateTimeKind.Local或DateTimeKind.Unspecified）。

                                SupportsMultipleTimezone：如果当前使用的时钟是UTC，则返回true。
                */

                /*
                    五、时区    Time Zones
                                        
                         1、时区设置   TimeZone Settings
                         
                                    ABP定义了一个设置，名为Abp.Timing.TimeZone，可用于设置和获取用户、租户或应用程序的全局时区。默认值为UTC。
                                    
                                    请参阅设置留档以了解有关设置系统的更多信息。

                        2、ITimezoneProvider 

                                    ITimezoneProvider是一项服务，可以简单地将Windows Time Zone(Windows 时区) Id值转换为Iana Time Zone Name（Iana 时区数据库）值，反之亦然。

                                    它还提供了获取这些时区列表并获得具有给定名称的TimeZoneInfo的方法。

                                    它是使用TimeZoneConverter库实现的。
                */
        </script>
    </body>
</html>    